<template>
  <el-card class="box-card">
    <div class="wzg-center width400">
      <el-form ref="formRef" :model="form" :rules="rules" v-loading="loading" label-width="150px">
        <el-row :gutter="10">
          <el-col :span="20">
            <el-form-item label="角色名称：" prop="name">
              <el-input v-model.trim="form.name" placeholder="角色名称"> </el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="20">
            <el-form-item label="权限管理：">
              <el-checkbox v-model.trim="selectAll">全选/不全选</el-checkbox>
            </el-form-item>
          </el-col>
        </el-row>
        <el-card shadow="never">
          <el-tree :data="menuData" show-checkbox node-key="id" ref="treeRef" default-expand-all :props="defaultProps" :default-checked-keys="checkedKeys" @check="handleCheckMenu"></el-tree>
        </el-card>
      </el-form>
      <div class="footer-center">
        <el-button :disabled="disabledbtn" @click="cancelSubmit">取 消</el-button>
        <el-button type="primary" :disabled="disabledbtn" v-if="!isDisabledbtn" @click="submitForm">确 定</el-button>
      </div>
    </div>
  </el-card>
</template>

<script setup lang="ts">
import type { postOrPutType } from "@/constants";
import type { ViewMode } from "@/types/common";
import type { TreeInstance } from "element-plus";
import { useState } from "@/hooks/useState.ts";
import { commonRoleInfo, getMyRoleInfo } from "@/utils/api/role";
import type { IRoleDTO } from "@/types/role";
import type { ICheckedKeys, IMenu, IMenuRole } from "@/types/menu";
const { disabledbtn, loading, toggleState } = useState();

const formStatus = defineModel<ViewMode>("formStatus", { required: true });
const form = defineModel<IRoleDTO>("form", { required: true });
const emit = defineEmits<{
  handleInitData: [];
  handleSuccess: [];
  handleCusCategoryRefresh: [];
}>();
const defaultProps = reactive({
  children: "items",
  label: "title"
});

const menuData = ref<Array<IMenuRole>>([]);
const allKeys = ref<Array<number>>([]);
const checkedKeys = ref<Array<number>>([104]);

const treeRef = ref<TreeInstance>(); /* 树的节点 */

const isDisabledbtn = ref(false);
const selectAll = ref(false);
const formRef = useTemplateRef("formRef");
const methodType = ref<postOrPutType>("PUT");

const rules = reactive({
  name: [{ required: true, message: "角色名称必填", trigger: "blur" }]
});

onMounted(() => {
  console.log("Component mounted!");
});

/* formStatus处理器 */
const statusHandlers: Record<ViewMode, () => void> = {
  view: () => {
    isDisabledbtn.value = true;
  },
  edit: () => {
    methodType.value = "PUT";
  },
  add: () => {
    methodType.value = "POST";
  },
  none: () => {
    /* 初始化数据 */
    handleInitData();
  }
};
/* 监听formStatus,新增，编辑，查看的时候都可以打开模态框，又是有不同的操作和效果，需要单独判断，none为模态框关闭的情况，需要初始化数据 */
watch(formStatus, newValue => {
  const handler = statusHandlers[newValue];
  handler?.();
});
watch(
  () => form.value.id,
  newV => {
    if (newV) {
      if (form.value.auth_ids !== null) {
        let newArr: Array<number> = [];
        console.log(new Set(form.value.auth_ids.split(",")));
        let auth_ids = [...new Set(form.value.auth_ids.split(","))];
        console.log(auth_ids);
        auth_ids.forEach((item: string) => {
          handleCheckedKeys(Number(item), menuData.value, newArr);
        });
        checkedKeys.value = newArr.map(Number);
        treeRef.value?.setCheckedKeys(checkedKeys.value);
        console.log(checkedKeys);
      }
    }
  }
);
/* 监听全选，全选的时候，需要把所有菜单的ID都给选中，并把选中的ID赋值给checkedKeys，并把选中的ID赋值给form.auth_ids */
watch(selectAll, newV => {
  console.log(newV);
  if (newV) {
    checkedKeys.value = allKeys.value;
    form.value.auth_ids = checkedKeys.value.join(",");
  } else {
    checkedKeys.value = [104];
    form.value.auth_ids = "104";
  }
  treeRef.value?.setCheckedKeys(checkedKeys.value);
});

/* 获取所有菜单信息 */
function handleGetMyRoleInfo() {
  getMyRoleInfo<Array<IMenuRole>>()
    .then(res => {
      if (res.status === 1 && res.result.length !== 0) {
        menuData.value = res.result;
        handleGetMenuIds(res.result);
        /* 系统首页 默认选中，并禁用 */
        for (let i = 0; i < menuData.value.length; i++) {
          /* 104不改 */
          if (menuData.value[i].id === 104) {
            menuData.value[i].disabled = true;
            break;
          }
        }
      }
    })
    .catch(() => {})
    .finally(() => {
      disabledbtn.value = false;
    });
}

/* 获取所有菜单的ID */
function handleGetMenuIds(menuData: Array<IMenuRole>) {
  for (let i = 0; i < menuData.length; i++) {
    allKeys.value.push(menuData[i].id);
    if (menuData[i].items.length > 0) {
      handleGetMenuIds(menuData[i].items);
    }
  }
}

/* 检查父级是否选中 */
const handleCheckedKeys = (id: number, data: Array<IMenuRole>, newArr: Array<number>) => {
  data.forEach(item => {
    if (item.id == id) {
      if (item.items.length == 0) {
        newArr.push(item.id);
      }
    } else {
      if (item.items.length != 0) {
        handleCheckedKeys(id, item.items, newArr);
      }
    }
  });
};
/* 初始化数据 */
function handleInitData() {
  methodType.value = "POST";
  isDisabledbtn.value = false;

  form.value.id = 0; /* 这个还需要手动清除 */
  form.value.auth_ids = "";
  selectAll.value = false;
  treeRef.value?.setCheckedKeys([104]);

  formRef.value?.resetFields();
  formRef.value?.clearValidate();
}

/* 保存或编辑 */
function submitForm() {
  if (!formRef.value) return;
  formRef.value.validate(valid => {
    if (!valid) {
      ElMessage.warning("请填写必填字段");
      return;
    }
    submitFormInfo();
  });
}

/* 保存或编辑信息 */
function submitFormInfo() {
  if (!handleValidAssignment()) return;
  /* 防止多次提交 */
  toggleState(true);
  commonRoleInfo(form.value, methodType.value)
    .then(res => {
      ElMessage.success(res.msg);
      cancelSubmit();
      emit("handleSuccess");
    })
    .catch(() => {})
    .finally(() => {
      toggleState(false);
    });
}
/* 保存或编辑 取消提交 */
function cancelSubmit() {
  // clearData();
  // activeName = "one";
  emit("handleInitData");
}

/* 自定义校验，提交表单前操作 */
function handleValidAssignment() {
  // let checkedNodes = treeRef.value!.getCheckedNodes();
  // console.log(checkedNodes);

  if (methodType.value === "PUT" && form.value.id === 0) {
    ElMessage.warning(`请点击右侧分配菜单进入`);
    return false;
  }
  if (form.value.auth_ids === "") {
    ElMessage.warning(`至少选择一个权限`);
    return false;
  }
  return true;
}

/* 点击tree事件 */
const handleCheckMenu = (_checkedNodes: IMenu, checkedKeys: ICheckedKeys) => {
  const auth_ids = [...checkedKeys.halfCheckedKeys, ...checkedKeys.checkedKeys];
  form.value.auth_ids = auth_ids.join(",");
};

handleGetMyRoleInfo();
</script>

<style lang="scss" scoped>
/* 修改select的盒模型 */
.el-select {
  display: block;
}
/* 底部按钮居中 */
.footer-center {
  margin: 10px 0;
  text-align: center;
}

.width400 {
  width: 400px;
}

.width800 {
  max-width: 800px;
}

.wzg-center {
  margin: auto;
  padding: 50px 50px 15px;
  border: 1px solid #ebeef5;
  border-radius: 5px;
}
</style>
